package org.angelica.utils.common;

import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * jwt token 工具类
 * @author aizhimin
 *
 */
public class JwtTokenUtil {
	
	/**
	 * 签发accessToken
	 * @param jwtSecretKey 秘钥
	 * @param issuer 签发人
	 * @param userId 用户id
	 * @return jwt
	 */
	public static String createAccessToken(String jwtSecretKey,String issuer,String userId,Map<String,Object> claims,long ttlMillis) {
		return createJwtToken(jwtSecretKey,issuer,userId,claims,ttlMillis);
	}
	
	/**
	 * 生成jwt token
	 * @param jwtSecretKey 秘钥
	 * @param issuer 签发者
	 * @param subject 主题
	 * @param claims 内容
	 * @param ttlMillis 签发时间
	 * @return String
	 */
	private static String createJwtToken(String jwtSecretKey,String issuer,String subject,Map<String,Object> claims,long ttlMillis) {
	    //当前时间戳
	    long currentTimeMillis = System.currentTimeMillis();
	    JwtBuilder jwtBuilder  =  Jwts.builder()
				//参数  一定先于下面的set方法，否则覆盖
				.setClaims(claims)
				//jwt token id
				.setId(UUID.randomUUID().toString().replaceAll("-", ""))
				.setSubject(subject)
				.setIssuer(issuer)
				.setIssuedAt(new Date(currentTimeMillis))
				.setExpiration(new Date(currentTimeMillis+ttlMillis))
				.compressWith(CompressionCodecs.GZIP)
				.signWith(SignatureAlgorithm.HS256, new SecretKeySpec(DatatypeConverter.parseBase64Binary(jwtSecretKey), SignatureAlgorithm.HS256.getJcaName()));

	    //压缩jwt为字符串
	    return jwtBuilder.compact();
    }
	
	
	
	/**
	 * 解析jwt
	 * @param jwtSecretKey 秘钥
	 * @param jwtToken jwt
	 * @return Claims
	 */
	public static Claims parseJwt(String jwtSecretKey,String jwtToken) {
		try {
			return Jwts.parser()
					.setSigningKey(DatatypeConverter.parseBase64Binary(jwtSecretKey))
					.parseClaimsJws(jwtToken).getBody();
		}catch (Exception e){
			return null;
		}
	}
	
	/**
	 * 从token中获取用户id
	 * @param jwtSecretKey 秘钥
	 * @param jwtToken jwttoken
	 * @return Long
	 */
	public static Long getUserIdFromToken(String jwtSecretKey,String jwtToken) {
		Claims claims = parseJwt(jwtSecretKey,jwtToken);
		if(claims != null){
			String subject = claims.getSubject();
			if(StringUtils.isNotBlank(subject)) {
				return Long.valueOf(subject);
			}
		}
		return null;
	}

	/**
	 * 从token中获取过期时间
	 * @param jwtSecretKey 秘钥
	 * @param token jwttoken
	 * @return long
	 */
	public static long getExpirationDateTime(String jwtSecretKey,String token) {
		Claims claims = JwtTokenUtil.parseJwt(jwtSecretKey,token);
		if(claims != null){
			return claims.getExpiration().getTime();
		}
		return 0;
	}

}
